﻿using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.XPath;

namespace GrailTechnology.OpenCalais
{
    public class Utils
    {
        public static string GetLicence
        {
            get
            {
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.APIKey"]))
                {
                    return ConfigurationManager.AppSettings["AutoTags.APIKey"];
                }

                return string.Empty;
            }
        }

        public static WebProxy GetProxy(out bool containsError)
        {
            containsError = false;
            if (
                string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.Proxy.Username"]) &&
                string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.Proxy.Password"]) && 
                string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.Proxy.Domain"]))
            {
                return null;
            }
            
            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.Proxy.Username"]) &&
                !string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.Proxy.Password"]) &&
                !string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.Proxy.Domain"]))
            {
                var proxy = new WebProxy
                                {
                                    Credentials = new NetworkCredential(
                                        ConfigurationManager.AppSettings["AutoTags.Proxy.Username"],
                                        ConfigurationManager.AppSettings["AutoTags.Proxy.Password"],
                                        ConfigurationManager.AppSettings["AutoTags.Proxy.Domain"])
                                };
                return proxy;
            }
            
            containsError = true;
            return null;
        }

        public static string ByteArrayToString(byte[] responseArray)
        {
            string response = Encoding.ASCII.GetString(responseArray);
            return response;
        }

        /// <summary>
        /// convert string to byte array
        /// </summary>
        /// <param name="sendParams">string to be converted</param>
        /// <returns>byte array</returns>
        public static byte[] PostToByteArray(string sendParams)
        {
            byte[] byteArray = Encoding.UTF8.GetBytes(sendParams);
            return byteArray;
        }

        public static string[] GetNodeProperties()
        {
            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["AutoTags.PropertyNames"]))
            {
                if (ConfigurationManager.AppSettings["AutoTags.PropertyNames"].ToLower() != "all")
                {
                    return ConfigurationManager.AppSettings["AutoTags.PropertyNames"].Split(';');
                }
            }

            return new string[1] {"all"};
        }

        public static bool IsRequiredProperty(string[] propertyNames, string propertyName)
        {
            foreach (string property in propertyNames)
            {
                if (property == propertyName)
                {
                    return true;
                }
            }

            return false;
        }

        public static List<string> ResponseToList(string text)
        {
            var tags = new List<string>();
            var doc = new XPathDocument(new StringReader(Decode(text)));

            var navigator = ((IXPathNavigable) doc).CreateNavigator();
            XPathNodeIterator nodes = navigator.Select("//*");

            while (nodes.MoveNext())
            {
                if (nodes.Current.Name == "CalaisSimpleOutputFormat")
                {
                    XPathNodeIterator newIter = nodes.Current.SelectDescendants(XPathNodeType.Element, false);
                    while (newIter.MoveNext())
                    {
                        AnalyseString(tags, newIter.Current.Name, newIter.Current.Value);
                    }
                    break;
                }
            }

            return tags;
        }

        private static void AnalyseString(List<string> list, string name, string value)
        {
            if (name != "Topics")
            {
                if (!IsUrl(value))
                {
                    if (name == "Company")
                    {
                        list.Add(value.Replace("_", " "));
                    }
                    else
                    {
                        list.AddRange(value.Split('_'));
                    }
                }
            }
        }

        public static bool IsUrl(string tag)
        {
            var match = Regex.Match(tag, @"^(http:\/\/|https:\/\/|ftp:\/\/)");
            return match.Success;
        }

        private static string Decode(string encoded)
        {
            return HttpUtility.UrlDecode(encoded).Replace("&lt;", "<").Replace("&gt;", ">");
        }
    }
}
